package com.fingard.dsp.bank.directbank.allinpay02;

import com.alibaba.fastjson.JSONObject;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.allinpay02.util.AppUtil;
import com.fingard.dsp.bank.directbank.allinpay02.util.SybUtil;
import com.fingard.dsp.bank.directbank.bankInterface.IOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.ReqOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.RetAtsOtherElse;
import com.fingard.text.MD5SaltHelper;
import com.fingard.text.StringHelper;
import org.apache.commons.lang.StringEscapeUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class AllInPay02OtherElse extends AllInPay02Base implements IOtherElse {
    public RetAtsOtherElse d_else(ReqOtherElse p_reqElse) throws Exception {
        String transType = p_reqElse.reqHeader.transType;
        if ("VerifySign".equals(transType)) {
            if ("GW01".equals(p_reqElse.reqHeader.commandCode)) {
                return verifyGateway(p_reqElse);
            } else if ("GW02".equals(p_reqElse.reqHeader.commandCode)) {
                return verifyGW02Gateway(p_reqElse);
            } else {
                return verifyUnifiedOrder(p_reqElse);
            }
        } else if ("PosQuery".equals(p_reqElse.reqHeader.transType)) {
            if ("PQ01".equals(p_reqElse.reqHeader.commandCode)) {
                return verifyPosQuery(p_reqElse);
            } else {
                return signPosQuery(p_reqElse);
            }
        } else if ("PosNotify".equals(p_reqElse.reqHeader.transType)) {
            if ("PS01".equals(p_reqElse.reqHeader.commandCode)) {
                return verifyPosNotify(p_reqElse);
            } else {
                return signPosNotify(p_reqElse);
            }
        } else if ("UnifiedSign".equals(transType)) {
            if ("POS".equals(p_reqElse.reqHeader.commandCode)) {
                return unifiedSignForPos(p_reqElse);
            }
        } else {
            RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

            retAts.retHashMap = new HashMap<String, String>();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", "未知的TransType：" + transType);

            return retAts;
        }
        return null;
    }

    public RetAtsOtherElse verifyGateway(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String ownAct = "";
            if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
                ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
            }

            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("Plain")) {
                plain = p_reqElse.reqHashMap.get("Plain");
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失验签原始串");

                return retAts;
            }

            ActSetItem actItem = getBankConfig().getActSetItemByAny(ownAct, "", "", "gateway");
            if (actItem != null) {
                JSONObject request = JSONObject.parseObject(plain);

                String merchantId = request.getString("merchantId");
                String version = request.getString("version");
                String language = request.getString("language");
                String signType = request.getString("signType");
                String payType = request.getString("payType");
                String issuerId = request.getString("issuerId");
                String paymentOrderId = request.getString("paymentOrderId");
                String orderNo = request.getString("orderNo");
                String orderDatetime = request.getString("orderDatetime");
                String orderAmount = request.getString("orderAmount");
                String payDatetime = request.getString("payDatetime");
                String payAmount = request.getString("payAmount");
                String ext1 = request.getString("ext1");
                String ext2 = request.getString("ext2");
                String payResult = request.getString("payResult");
                String errorCode = request.getString("errorCode");
                String returnDatetime = request.getString("returnDatetime");
                String signMsg = request.getString("signMsg");

                //构造订单结果对象，验证签名。
                com.allinpay.ets.client.PaymentResult paymentResult = new com.allinpay.ets.client.PaymentResult();
                paymentResult.setMerchantId(merchantId);
                paymentResult.setVersion(version);
                paymentResult.setLanguage(language);
                paymentResult.setSignType(signType);
                paymentResult.setPayType(payType);
                paymentResult.setIssuerId(issuerId);
                paymentResult.setPaymentOrderId(paymentOrderId);
                paymentResult.setOrderNo(orderNo);
                paymentResult.setOrderDatetime(orderDatetime);
                paymentResult.setOrderAmount(orderAmount);
                paymentResult.setPayDatetime(payDatetime);
                paymentResult.setPayAmount(payAmount);
                paymentResult.setExt1(ext1);
                paymentResult.setExt2(ext2);
                paymentResult.setPayResult(payResult);
                paymentResult.setErrorCode(errorCode);
                paymentResult.setReturnDatetime(returnDatetime);
                paymentResult.setKey(actItem.saltKey);
                paymentResult.setSignMsg(signMsg);

                //signType为"1"时，必须设置证书路径。
                if ("1".equals(signType)) {
                    paymentResult.setCertPath(actItem.oppCertFilePath);
                }

                // 执行验签
                boolean verifySignResult = paymentResult.verify();
                if (verifySignResult) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验签通过");
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "验签失败");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse verifyGW02Gateway(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String ownAct = "";
            if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
                ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
            }

            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("Plain")) {
                plain = p_reqElse.reqHashMap.get("Plain");
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失验签原始串");

                return retAts;
            }

            ActSetItem actItem = getBankConfig().getActSetItemByAny(ownAct, "", "", "unifiedorder");
            if (actItem != null) {
                WriteBankLogLn2("通联收银宝网关支付异步通知验签原文:\r\n" + plain);

                TreeMap<String, String> params = getParams(plain);

                // 执行验签
                boolean verifySignResult = AppUtil.validSign(params, actItem.saltKey);
                if (verifySignResult) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验签通过");
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "验签失败");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse verifyUnifiedOrder(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String ownAct = "";
            if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
                ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
            }

            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("Plain")) {
                plain = p_reqElse.reqHashMap.get("Plain");
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失验签原始串");

                return retAts;
            }

            ActSetItem actItem = getBankConfig().getActSetItemByAny(ownAct, "", "", "unifiedorder");
            if (actItem != null) {
                WriteBankLogLn2("通联统一下单异步通知验签原文:\r\n" + plain);

                TreeMap<String, String> params = getParams(plain);

                // 执行验签
                boolean verifySignResult = SybUtil.validSign(params, actItem.saltKey);
                if (verifySignResult) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验签通过");
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "验签失败");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse verifyPosQuery(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
                plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
                return retAts;
            }

            // 验签
            Map<String, String> posQueryMap = convertToMap(plain);

            String sign = posQueryMap.get("sign");

            String merchantId = posQueryMap.get("cusid");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "pos");
            if (actItem != null) {
                posQueryMap.put("key", actItem.saltKey);
                String signData = getSignStr(posQueryMap);
                WriteBankLogLn2("待签名数据:\r\n" + signData);

                String tmpSign = SybUtil.md5(signData.getBytes(getCharset("UTF-8", "pos")));
                if (sign.equals(tmpSign)) {
                    JSONObject result = new JSONObject();
                    result.put("Rdseq", posQueryMap.get("bizseq"));
                    result.put("IsRefund", "false");
                    result.put("ReserveField", signData);

                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验签通过");
                    retAts.retHashMap.put("Result", result.toJSONString());
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "验签失败!");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号:" + merchantId + "商户配置信息!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse signPosQuery(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
                plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
                return retAts;
            }

            JSONObject reqJson = JSONObject.parseObject(plain);
            String reserveField = reqJson.getString("ReserveField");
            Map<String, String> reqMap = convertToMap(reserveField);

            String merchantId = reqMap.get("cusid");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "pos");
            if (actItem != null) {
                Map<String, String> signMap = new HashMap<String, String>();
                signMap.put("appid", reqMap.get("appid"));
                signMap.put("cusid", reqMap.get("cusid"));
                signMap.put("trxcode", reqMap.get("trxcode"));
                signMap.put("timestamp", reqMap.get("timestamp"));
                signMap.put("randomstr", reqMap.get("randomstr"));
                signMap.put("bizseq", reqMap.get("bizseq"));

                String retCode = "";
                String retMsg = "";
                String returnCode = reqJson.getString("ReturnCode");
                if ("success".equals(returnCode)) {
                    retCode = "0000";
                    retMsg = "处理成功";
                } else {
                    retCode = "9999";
                    retMsg = "交易失败";// todo
                }
                signMap.put("retcode", retCode);
                signMap.put("retmsg", retMsg);
                signMap.put("amount", StringHelper.amountMultiply100(reqJson.getString("Amount")));
                signMap.put("trxreserve", reqMap.get("trxreserve"));
                signMap.put("key", actItem.saltKey);

                String sign = signWithMD5(signMap);
                signMap.put("sign", sign);

                JSONObject result = new JSONObject();
                result.put("appid", reqMap.get("appid"));
                result.put("cusid", reqMap.get("cusid"));
                result.put("trxcode", reqMap.get("trxcode"));
                result.put("timestamp", reqMap.get("timestamp"));
                result.put("randomstr", reqMap.get("randomstr"));
                result.put("sign", signMap.get("sign"));
                result.put("bizseq", signMap.get("bizseq"));
                result.put("retcode", signMap.get("retcode"));
                result.put("retmsg", signMap.get("retmsg"));
                result.put("amount", signMap.get("amount"));
                result.put("trxreserve", signMap.get("trxreserve"));

                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "");
                retAts.retHashMap.put("Result", result.toJSONString());
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号:" + merchantId + "商户配置信息!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse verifyPosNotify(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
                plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
                return retAts;
            }

            // 验签
            Map<String, String> posNotify = convertToMap(plain);

            String sign = posNotify.get("sign");

            String merchantId = posNotify.get("cusid");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "pos");
            if (actItem != null) {
                posNotify.put("key", actItem.saltKey);
                String signData = getSignStr(posNotify);
                WriteBankLogLn2("待签名数据:\r\n" + signData);

                String tmpSign = SybUtil.md5(signData.getBytes(getCharset("UTF-8", "pos")));
                if (sign.equals(tmpSign)) {
                    JSONObject result = new JSONObject();
                    result.put("Rdseq", posNotify.get("bizseq"));
                    result.put("IsRefund", "false");
                    result.put("ReserveField", signData);
                    result.put("PayState", posNotify.get("trxstatus"));
                    result.put("PayInfoCode", posNotify.get("trxstatus"));
                    result.put("PayInfo", "");
                    result.put("Amount", StringHelper.amountDivide100(posNotify.get("amount")));
                    result.put("Asknumber", posNotify.get("trxid"));
                    result.put("Abstracts", "");
                    result.put("PayMadeDate", posNotify.get("paytime"));
                    result.put("OurBankAccount", "");
                    result.put("OppBankAccount", posNotify.get("acct"));
                    result.put("OppBankCode", "");
                    result.put("Reserved01", "");
                    result.put("Reserved02", "");

                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验签通过");
                    retAts.retHashMap.put("Result", result.toJSONString());
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "验签失败!");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号:" + merchantId + "商户配置信息!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse signPosNotify(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
                plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
                return retAts;
            }

            retAts.retHashMap.put("RespCode", "0");
            retAts.retHashMap.put("RespInfo", "");

            JSONObject reqJson = JSONObject.parseObject(plain);
            String status = reqJson.getString("ReturnCode");
            if ("success".equals(status)) {
                retAts.retHashMap.put("Result", "success");
            } else {
                retAts.retHashMap.put("Result", "error");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    /**
     * POS保单信息查询签名
     *
     * @param p_reqElse
     * @return
     */
    public RetAtsOtherElse unifiedSignForPos(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            Map<String, String> mapParams = p_reqElse.reqHashMap;
            mapParams = removeHead(mapParams);

            String tmpSignData = getSignData(mapParams);
            tmpSignData += "&key=" + getBankConfig().getValueAsString("saltKey");
            WriteBankLogLn2("待签名数据:\r\n" + tmpSignData);
            String sign = MD5SaltHelper.md5(tmpSignData, getCharset("UTF-8", "pos"));
            WriteBankLogLn2("签名结果:" + sign);
            if (StringHelper.hasAnyChar(sign)) {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "");
                retAts.retHashMap.put("Result", sign);
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "签名失败!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }
}
